﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Web;

namespace GMS.BIZ
{
    public class PaperFile
    {
        private string file_pre = @"d:\GMSUploadFile";

        #region Property
        private int style;
        public int Style
        {
            get { return style; }
            //set { style = value; }
        }
        private string studentID;
        public string StudentID
        {
          get { return studentID; }
          //set { studentID = value; }
        }
        private string teacherID;
        public string TeacherID
        {
            get { return teacherID; }
            //set { teacherID = value; }
        }
        #endregion Property

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="style">类型：1－6</param>
        /// <param name="studentID">学生学号</param>
        /// <param name="teacherID">教师工号</param>
        public PaperFile(int style,string studentID,string teacherID)
        {
            this.style = style;
            this.studentID = studentID;
            this.teacherID = teacherID;
        }

        /// <summary>
        /// 上传一个文件
        /// </summary>
        /// <param name="comment">评论</param>
        /// <param name="role">当前用户角色</param>
        /// <param name="uploadStream">上传文件的流</param>
        /// <param name="fileType">文件后缀名（包括“.”）</param>
        public string UploadFile(string comment, string role,System.IO.Stream uploadStream,string fileType)
        {
            //制作model
            GMS.ORM.Model.PFile myPFile = new GMS.ORM.Model.PFile();
            myPFile.style = this.style;
            myPFile.uploadtime = DateTime.Now;
            myPFile.comment = comment;
            if (role == "t")
            {
                myPFile.uploader_from = this.teacherID;
                myPFile.uploader_to = this.studentID;
            }
            else if (role == "s")
            {
                myPFile.uploader_from = this.studentID;
                myPFile.uploader_to = this.teacherID;
            }
            else return ErrorMessage.FieldWrongType;

            string styleName;
            switch (this.style)
            {
                case 1: styleName = Docs.Doc1; break;
                case 2: styleName = Docs.Doc2; break;
                case 3: styleName = Docs.Doc3; break;
                case 4: styleName = Docs.Doc4; break;
                case 5: styleName = Docs.Doc5; break;
                case 6: styleName = Docs.Doc6; break;
                default: return ErrorMessage.FieldWrongType;
            }
            //*************************************************
            //文件名的命名方式：学号_姓名_style_日期A
            //文件名的命名方式：学号_姓名_style_日期B
            //教师回复命名方式：Reply_学号_姓名_style_日期B
            //*************************************************
            myPFile.filename = this.studentID + "_" + Student.GetName(this.studentID) + "_" + styleName + "_";
            myPFile.filename = myPFile.filename + DateTime.Today.Year.ToString() + AddZero(DateTime.Today.Month) + AddZero(DateTime.Today.Day);
            //如果是教师，则加上"回复"
            if (role == "t")
                myPFile.filename = "Reply_" + myPFile.filename;
            //当天内第几个文件
            try
            {
                int howMany = CountTodayPaper(myPFile.uploader_from, myPFile.uploader_to, this.style) + 1;
                myPFile.filename = myPFile.filename + "(" + howMany.ToString() + ")";
                myPFile.filename = myPFile.filename + fileType;
            }
            catch (Exception ex)
            { return ex.ToString(); }

            //检查文件夹是否存在，创建它如果不存在
            try
            {
                DirectoryInfo dir = new DirectoryInfo(this.file_pre + @"\" + this.studentID);
                dir.Create();
            }
            catch (Exception ex)
            { Console.Write(ex.ToString()); }

            //上传文件
            this.StreamToFile(uploadStream, this.file_pre + @"\" + this.studentID.ToString() + @"\" + myPFile.filename);
            
            //将model写入数据库
            GMS.ORM.DAL.PFile optPFile = new GMS.ORM.DAL.PFile();
            bool ok = optPFile.Add(myPFile);
            if (!ok) return ErrorMessage.DBOptError;
            else return ErrorMessage.OK;
        }

        private string AddZero(int number)
        {
            if (number < 10)
                return "0" + number.ToString();
            else
                return number.ToString();
        }

        /// <summary>
        /// 将 Stream 写入文件
        /// </summary>
        /// <param name="stream">Stream</param>
        /// <param name="fileName">文件名</param>
        private bool StreamToFile(Stream stream, string fileName)
        {
            try
            {
                // 把 Stream 转换成 byte[]
                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, bytes.Length);
                // 设置当前流的位置为流的开始
                stream.Seek(0, SeekOrigin.Begin);
                // 把 byte[] 写入文件
                FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);
                BinaryWriter bw = new BinaryWriter(fs);
                bw.Write(bytes);
                bw.Close();
                fs.Close();
                return true;
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 从文件读取 Stream
        /// </summary>
        /// <param name="fileName">文件名</param>
        public Stream FileToStream(string fileName)
        {
            try
            {
                // 打开文件
                FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                // 读取文件的 byte[]
                byte[] bytes = new byte[fileStream.Length];
                fileStream.Read(bytes, 0, bytes.Length);
                fileStream.Close();
                // 把 byte[] 转换成 Stream
                Stream stream = new MemoryStream(bytes);
                return stream;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return null;
            }
        }

        /// <summary>
        /// 数当天某类型的文件数量
        /// </summary>
        /// <param name="_from">发送人</param>
        /// <param name="_to">接受人</param>
        /// <param name="_style">类型</param>
        private int CountTodayPaper(string _from,string _to,int _style)
        {
            GMS.ORM.DAL.PFile optPFile = new GMS.ORM.DAL.PFile();
            DataSet ds = optPFile.GetList("uploader_from='" + _from + "' AND uploader_to='" + _to + "' AND datepart(day,uploadtime)=datepart(day,getdate()) AND datepart(month,uploadtime)=datepart(month,getdate()) AND datepart(year,uploadtime)=datepart(year,getdate()) AND style=" + _style.ToString());
            return ds.Tables[0].Rows.Count;
        }

        /// <summary>
        /// 下载文件（通用）
        /// </summary>
        /// <param name="FileName">文件名</param>
        static public void Download(string FileName)
        {
            System.IO.FileStream r = new System.IO.FileStream(FileName, System.IO.FileMode.Open);    //文件下载实例化
            //设置基本信息  
            HttpContext.Current.Response.Buffer = false;
            HttpContext.Current.Response.AddHeader("Connection", "Keep-Alive");

            //读取文件类型
            string fileType = System.IO.Path.GetExtension(FileName);
            switch (fileType)
            {
                case ".doc": HttpContext.Current.Response.ContentType = "application/msword"; break;
                case ".zip": HttpContext.Current.Response.ContentType = "application/zip"; break;
                case ".rar": HttpContext.Current.Response.ContentType = "application/x-msdownload ; Charset=utf-8"; break;
                default: HttpContext.Current.Response.ContentType = "text/plain asc"; break;
            }            

            HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + System.IO.Path.GetFileName(FileName)); // 此处文件名如果是中文在浏览器默认是筹码,应该加HttpUtility.UrlEncode(filename) 
            HttpContext.Current.Response.AddHeader("Content-Length", r.Length.ToString());
            while (true)    //如果文件大于缓冲区，通过while循环多次加载文件
            {
                //开辟缓冲区空间  
                byte[] buffer = new byte[1024];
                //读取文件的数据  
                int leng = r.Read(buffer, 0, 1024);
                if (leng == 0)             //到文件尾，结束  
                    break;
                if (leng == 1024)            //读出的文件数据长度等于缓冲区长度，直接将缓冲区数据写入  
                    HttpContext.Current.Response.BinaryWrite(buffer);           //向客户端发送数据流
                else
                {
                    //读出文件数据比缓冲区小，重新定义缓冲区大小，只用于读取文件的最后一个数据块  
                    byte[] b = new byte[leng];
                    for (int i = 0; i < leng; i++)
                        b[i] = buffer[i];
                    HttpContext.Current.Response.BinaryWrite(b);
                }
            }

            r.Close();//关闭下载文件  
            HttpContext.Current.Response.End();//结束文件下载
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="id">文件号</param>
        public void GetOneFile(decimal id)
        {
            GMS.ORM.DAL.PFile optPFile = new GMS.ORM.DAL.PFile();
            if (optPFile.Exists(id))
            {
                string filePath = optPFile.GetModel(id).filename;
                filePath = file_pre + @"\" + this.studentID + @"\" + filePath;
                PaperFile.Download(filePath);
            }
        }

        /// <summary>
        /// 修改交付物状态。如果状态为1（通过），必须指定文件号。
        /// </summary>
        /// <param name="newStatus">新的状态号</param>
        /// <param name="id">文件号</param>
        public string ChangeStatus(int newStatus, decimal? id)
        {
            //拿
            GMS.ORM.Model.PGuide myPGuide = new GMS.ORM.Model.PGuide();
            GMS.ORM.DAL.PGuide optPGuide = new GMS.ORM.DAL.PGuide();
            myPGuide = optPGuide.GetModel(this.studentID, DeadLine.GetDeadLineYear());
            //若修改为状态1，则必须指定文件号
            if (newStatus == 1)
            {
                if (id == null || id == 0)
                    return ErrorMessage.FieldEmpty;
                switch (this.style)
                {
                    case 1: myPGuide.doc1id = id; break;
                    case 2: myPGuide.doc2id = id; break;
                    case 3: myPGuide.doc3id = id; break;
                    case 4: myPGuide.doc4id = id; break;
                    case 5: myPGuide.doc5id = id; break;
                    case 6: myPGuide.doc6id = id; break;
                    default: return ErrorMessage.NoSuchData;
                }
            }
            //改
            switch (this.style)
            {
                case 1: myPGuide.doc1 = newStatus; break;
                case 2: myPGuide.doc2 = newStatus; break;
                case 3: myPGuide.doc3 = newStatus; break;
                case 4: myPGuide.doc4 = newStatus; break;
                case 5: myPGuide.doc5 = newStatus; break;
                case 6: myPGuide.doc6 = newStatus; break;
                default: return ErrorMessage.NoSuchData;
            }
            //放
            bool ok = optPGuide.Update(myPGuide);
            if (!ok) return ErrorMessage.DBOptError;
            else return ErrorMessage.OK;
        }

        /// <summary>
        /// 获得批量的文件上传的DataSet
        /// </summary>
        public DataSet GetConversationFile()
        {
            GMS.ORM.DAL.PFile optPFile = new GMS.ORM.DAL.PFile();
            return optPFile.GetList("(uploader_from='" + this.studentID + "' OR uploader_to='" + this.studentID + "') AND style=" + this.style.ToString() + " ORDER BY uploadtime DESC");
        }
        /// <summary>
        /// 获得定时的批量的文件上传的DataSet
        /// </summary>
        /// <param name="from">从此时间开始</param>
        /// <param name="to">到此时间结束</param>
        public DataSet GetConversationFile(DateTime from, DateTime to)
        {
            GMS.ORM.DAL.PFile optPFile = new GMS.ORM.DAL.PFile();
            return optPFile.GetList("(uploader_from='" + this.studentID + "' OR uploader_to='" + this.studentID + "' AND uploadtime>" + from.ToString() + " AND uploadtime<" + to.ToString() + ") AND style=" + this.style.ToString() + " ORDER BY uploadtime DESC");
        }
        
        
        //获取通过文件的文件名
        static public string GetFileName(decimal fileid)
        {
            GMS.ORM.DAL.PFile optPFile = new GMS.ORM.DAL.PFile();
            GMS.ORM.Model.PFile myPFile = new GMS.ORM.Model.PFile();
            myPFile = optPFile.GetModel(fileid);
            return myPFile.filename;
        }
    }
}
